home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Periodicals / develop / develop 2 code / Secret Life of Mem. Mgr. / HeapDemo.p < prev    next >
Encoding:
Text File  |  1990-05-29  |  12.2 KB  |  442 lines  |  [TEXT/MPS ]

  1. program HeapDemo;
  2. (* Written by Richard Clark (AppleLink, GEnie: RDCLARK *)
  3. (*                              Internet: rdclark@apple.com or rdclark@applelink.apple.com) *)
  4. (* Copyright (c) 1989-1990 by Apple Computer, Inc. All Rights Reserved                       *)
  5.  
  6. (* See the "Globals" file for a description of the program *)
  7.  
  8. (* Segmentation: Put everything except "UDialogs" into CODE 1. The Dialog file *)
  9. (* goes into CODE 2.                                                                             *)
  10.  
  11. (* CHANGES SINCE VERSION 1.3.3 *)
  12. (* 1. Removed the spurious reference to "UMonitor" (some personal debugging code) *)
  13. (* 2. Updated menu select logic for the Window and Special menus *)
  14.  
  15.     uses
  16.         Types, Memory, Menus, Dialogs, SegLoad, Resources, OSUtils, ToolUtils, 
  17.         Fonts, Events, OSEvents, Desk, Windows,
  18.         UGlobals, UDialogs, UHeapHandler, UAboutWindow;
  19.  
  20.     var
  21.         DragLimits, SizeLimits: Rect;
  22.  
  23.  
  24.     procedure SafetyNet;
  25.    (* Procedure invoked when you press "resume" in the System Error dialog *)
  26.     begin
  27.         ExitToShell;
  28.     end; (* SafetyNet *)
  29.  
  30.  
  31.     procedure InitDemoZone;
  32.      (* This initializes our heap zone records and allocates the "mini" heap zone *)
  33.         var
  34.             miniHeapSize: LONGINT;
  35.  
  36.     begin
  37.         miniHeapSize := (MyHeapSize * 1024) + HeapBias + HeapTrailer + Slop;
  38.         theMiniHeap := NewPtr(miniHeapSize);  (* get enough room for our zone, plus a 52-byte *)
  39.                                                                       (* header and a 12-byte trailer *)
  40.         InitZone(nil, 64, Ptr(ORD(theMiniHeap) + miniHeapSize), theMiniHeap);
  41.         MyDemoZone := GetZone;
  42.  
  43.         ZeroHeapInfo(CurrHeap);                    (* Erase the "CurrHeap" array *)
  44.         ZeroHeapInfo(OldHeap);                    (* Erase the "OldHeap" array *)
  45.  
  46.         UpdateHeapInfo(CurrHeap, kClearDirtyFlags);
  47.         CopyHeapInfo(CurrHeap, OldHeap);         (* Copy such things as the free memory counts *)
  48.         SetZone(MyAppZone);                        (* makse sure that we're in the correct heap zone *)
  49.     end; (* InitDemoZone *)
  50.  
  51.  
  52.     procedure Initialize;
  53.  
  54.         procedure InitMyMenus;
  55.         begin
  56.             AppleMenu := GetMenu(mApple);
  57.             AddResMenu(AppleMenu, 'DRVR');
  58.             InsertMenu(AppleMenu, 0);
  59.  
  60.             FileMenu := GetMenu(mFile);
  61.             InsertMenu(FileMenu, 0);
  62.  
  63.             EditMenu := GetMenu(mEdit);
  64.             InsertMenu(EditMenu, 0);
  65.  
  66.             WindowMenu := GetMenu(mWindow);
  67.             InsertMenu(WindowMenu, 0);
  68.  
  69.             SpecialMenu := GetMenu(mSpecial);
  70.             InsertMenu(SpecialMenu, 0);
  71.  
  72.             DrawMenuBar;
  73.         end; (* InitMyMenus *)
  74.  
  75.  
  76.         procedure CheckPrefs;
  77.      (* Look at the 'pref' 1000 resource to determine if we should open the Advanced or Novice *)
  78.     (* dialog at startup. If the resource contains $0000 as the first entry, it's the Novice dialog *)
  79.      (* If it contains $FFFF, it's the Advanced. (Actually, I only look at the least signifigant bit of *)
  80.     (* the first byte) *)
  81.  
  82.             type
  83.                 CharPtr = ^CHAR;
  84.                 CharHand = ^CharPtr;
  85.  
  86.             var
  87.                 prefsHand: Handle;
  88.  
  89.         begin
  90.             prefsHand := GetResource('pref', 1000);
  91.             if PrefsHand = nil then
  92.                 application.UseExtendedDialog := FALSE
  93.             else
  94.                 application.UseExtendedDialog := (ORD(CharHand(prefsHand)^^) <> 0);
  95.             CheckItem(WindowMenu, imSimpleDialog, not application.UseExtendedDialog);
  96.             CheckItem(WindowMenu, imComplexDialog, application.UseExtendedDialog);
  97.         end; (* CheckPrefs *)
  98.  
  99.         procedure CheckEnvirons;
  100.      (* Look for the 128K (or later) ROMS and WaitNextEvent *)
  101.             var
  102.                 rom: integer;       (* Which version of the ROM are we running? *)
  103.                 machine: integer; (* Which machine is this?? *)
  104.  
  105.             function TrapAvailable (tNumber: INTEGER; tType: TrapType): BOOLEAN;
  106.  
  107.                 const
  108.                     UnimplementedTrapNumber = $A89F;  {number of "unimplemented trap"}
  109.  
  110.             begin {TrapAvailable}
  111.  
  112.          {Check and see if the trap exists.}
  113.          {On 64K ROM machines, tType will be ignored.}
  114.  
  115.                 TrapAvailable := (NGetTrapAddress(tNumber, tType) <> GetTrapAddress(UnimplementedTrapNumber));
  116.  
  117.             end;  {TrapAvailable}
  118.  
  119.             const
  120.                 WNETrapNumber = $A860; {trap number of WaitNextEvent}
  121.                 TEStylNewTrapNumber = $A83E; { trap number of TEStylNew }
  122.  
  123.         begin
  124.             Environs(rom, machine);  (* Make sure that we can call SysEnvirons -- the LSP glue doesn't *)
  125.             if (rom >= 117) then      (* This is a Mac 512Ke or later , so we can see if we have WaitNextEvent *)
  126.                 begin
  127.                     system.EnhancedROMs := TRUE;
  128.                     system.HasWNE := TrapAvailable(WNETrapNumber, ToolTrap);
  129.                     system.HasStyledTE := TrapAvailable(TEStylNewTrapNumber, ToolTrap);
  130.                 end
  131.             else
  132.                 begin
  133.                     system.EnhancedROMs := FALSE;
  134.                     system.HasWNE := FALSE;
  135.                     system.HasStyledTE := FALSE;
  136.                 end;
  137.         end; (* CheckEnvirons *)
  138.  
  139.     begin
  140.         MaxApplZone;                                    (* Expand the heap to full size *)
  141.         MoreMasters;                                (* Allocate 64 Mac Programmers *)
  142.         MoreMasters;
  143.  
  144.         InitGraf(@ThePort);                            (* Just your everyday ROM initialization *)
  145.         InitFonts;
  146.         InitWindows;
  147.         InitMenus;
  148.         TEInit;
  149.         InitDialogs(@SafetyNet);
  150.         InitMyMenus;
  151.  
  152.         DragLimits := screenBits.bounds;
  153.         InsetRect(dragLimits, 4, 4);
  154.         DragLimits.top := 40;
  155.  
  156.         SizeLimits := screenBits.bounds;
  157.         InsetRect(SizeLimits, 64, 64);
  158.  
  159.         MyAppZone := GetZone;                         (* Get and remember the current heap zone *)
  160.         InitDemoZone;                         (* Create the Demo Heap *)
  161.         InitAboutWindow;
  162.         Quit := FALSE;
  163.         FlushEvents(everyEvent, 0);
  164.         CheckEnvirons;                    (* Look for WaitNextEvent *)
  165.         CheckPrefs;                        (* Decide which dialog (Novice or Advanced) to open at startup *)
  166.  
  167.         InitMyDialogs;                    (* Open the dialog *)
  168.         InitCursor;                        (* Initialize dialog-related global variables *)
  169.     end; (* initialize *)
  170.  
  171.     procedure CloseAWindow (whichWindow: WindowPtr);
  172.    (* This closes the specified window *)
  173.         var
  174.             wPeek: WindowPeek;
  175.             wKind: integer;
  176.  
  177.     begin
  178.         wPeek := WindowPeek(whichWindow);     (* See if we have an open window, and find out if it belongs *)
  179.         wKind := wPeek^.windowKind;                (* to a Desk Accessory *)
  180.       (* "CODE FROM MARS" ALERT: We're going directly into the WindowPeek record, but there's *)
  181.      (* no alternative. Look here if the program breaks in the future.                                    *)
  182.         if (wKind < 0) then
  183.             CloseDeskAcc(wKind)                          (* The frontmost window is a D.A., so kill it *)
  184.         else if not CloseIfAboutWindow(whichWindow) then
  185.             case GetWRefCon(whichWindow) of
  186.                 MemDialogRefCon:                       (* this is the main display *)
  187.                     CloseMemoryDialog;
  188.  
  189.                 LegendRefCon:                             (* This is the "legend" display *)
  190.                     begin
  191.                         ReleaseResource(Handle(WindowPeek(whichWindow)^.windowPic));
  192.                         DisposeWindow(whichWindow);
  193.                         EnableItem(WindowMenu, imShowLegend);
  194.                     end;
  195.  
  196.             end; (* GoAway *)
  197.     end;
  198.  
  199.  
  200.     procedure DoMenus (menuCode: longint);
  201.         var
  202.             inMenu, inItem: integer;
  203.         (* The following variables are used when opening a desk accessory *)
  204.             oldPort: GrafPtr;
  205.             ItemName: Str255;
  206.             status: integer;
  207.         (* The following is used when closing a window *)
  208.             wKind: integer; (* The WindowKind field of this window *)
  209.         (* The following is used when switching from the basic dialog to the advanced one *)
  210.             oldValue, newValue: Boolean;
  211.  
  212.         procedure DoApple (inItem: INTEGER);
  213.     (* Handle clicks in the Apple menu *)
  214.  
  215.         begin
  216.             if inItem = iaAbout then
  217.                 OpenAboutWindow
  218.             else
  219.                 begin
  220.                     GetPort(oldPort);
  221.                     GetItem(AppleMenu, inItem, ItemName);
  222.                     status := OpenDeskAcc(ItemName);
  223.                     SetPort(oldPort);
  224.                 end;
  225.         end; (* DoApple *)
  226.  
  227.         procedure DoFile (inItem: INTEGER);
  228.         begin
  229.             case inItem of
  230.                 ifOpen: 
  231.                     OpenMemoryDialog;
  232.  
  233.                 ifClose: 
  234.                     CloseAWindow(FrontWindow);
  235.  
  236.                 ifQuit: 
  237.                     Quit := TRUE;
  238.             end; (* case inItem *)
  239.         end; (* InItem *)
  240.  
  241.         procedure DoEdit (inItem: INTEGER);
  242.         begin
  243.          (* It's sure a good thing the Edit menu is disabled, eh? *)
  244.         end; (* DoEdit *)
  245.  
  246.         procedure DoWindow (inItem: INTEGER);
  247.             var
  248.                 legendWindow: WindowPtr;
  249.  
  250.         begin
  251.             case inItem of
  252.                 imSimpleDialog, imComplexDialog:
  253.              (* Switch from the Novice to the Advanced dialog, or vice versa *)
  254.                     begin
  255.                         oldValue := application.UseExtendedDialog;
  256.                         newValue := inItem = imComplexDialog;
  257.                         if (newValue <> oldValue) then
  258.                             begin
  259.                                 application.UseExtendedDialog := newValue;
  260.                                 CheckItem(WindowMenu, imSimpleDialog, not application.UseExtendedDialog);
  261.                                 CheckItem(WindowMenu, imComplexDialog, application.UseExtendedDialog);
  262.                                 CloseMemoryDialog;        (* Close the present dialog *)
  263.                                 OpenMemoryDialog;         (* Open the new one (which will display the same heap info) *)
  264.                             end;
  265.                     end;
  266.  
  267.                 imShowLegend:
  268.              (* Open a "legend" window, and attach a WindowPic *)
  269.                     begin
  270.                         legendWindow := GetNewWindow(wLegend, nil, WindowPtr(-1));
  271.                         if (legendWindow <> nil) then
  272.                             begin
  273.                                 WindowPeek(legendWindow)^.windowPic := PicHandle(GetResource('PICT', 1001));
  274.                                 SetWRefCon(legendWindow, LegendRefCon);
  275.                                 ShowWindow(legendWindow);
  276.                                 DisableItem(WindowMenu, imShowLegend);
  277.                             end;
  278.                     end;
  279.  
  280.             end; (* CASE *)
  281.         end; (* DoWindow *)
  282.  
  283.  
  284.         procedure DoSpecial (inItem: INTEGER);
  285.       (* This routine only supports 1 command: "clear the heap" *)
  286.         begin
  287.             if (theMiniHeap <> nil) then
  288.                 if (NoteAlert(aConfirmErase, nil) = 1) then
  289.                     begin
  290.                         DisposPtr(theMiniHeap);
  291.                         InitDemoZone;
  292.                         InitMemoryDialog;
  293.                         InvalItem(dmOldHeap);
  294.                         InvalItem(dmNewHeap);
  295.                         DisableItem(SpecialMenu, isEraseHeap);
  296.                         DrawMenuBar;
  297.                     end;
  298.         end; (* DoSpecial *)
  299.  
  300.     begin
  301.         if (menuCode <> 0) then
  302.             begin
  303.                 inMenu := HiWord(menuCode);
  304.                 inItem := LoWord(menuCode);
  305.                 case inMenu of
  306.                     mApple: 
  307.                         DoApple(inItem);
  308.  
  309.                     mFile: 
  310.                         DoFile(inItem);
  311.  
  312.                     mEdit: 
  313.                         DoEdit(inItem);
  314.  
  315.                     mWindow: 
  316.                         DoWindow(inItem);
  317.  
  318.                     mSpecial: 
  319.                         DoSpecial(inItem);
  320.  
  321.                 end; (* case *)
  322.                 HiliteMenu(0);
  323.             end;
  324.     end; (* DoMenus *)
  325.  
  326.  
  327.     procedure MainLoop;
  328.         var
  329.             theEvent: EventRecord;
  330.             realEvent: Boolean;
  331.  
  332.         procedure DoMouseDown (theEvent: EventRecord);
  333.             var
  334.                 location: integer;
  335.                 WhichWindow: WindowPtr;
  336.                 MenuCode: longint;
  337.                 sizeCode: longint;
  338.  
  339.         begin
  340.             location := FindWindow(theEvent.where, whichWindow);
  341.             case location of
  342.                 inMenuBar: 
  343.                     begin
  344.                         if FrontWindow <> nil then
  345.                             EnableItem(fileMenu, ifClose)
  346.                         else
  347.                             DisableItem(fileMenu, ifClose);
  348.                         MenuCode := MenuSelect(theEvent.where);
  349.                         DoMenus(MenuCode);
  350.                     end;
  351.  
  352.                 inContent: 
  353.                     if (whichWindow <> FrontWindow) then
  354.                         begin
  355.                             SelectWindow(whichWindow);                    (* Bring it to the front *)
  356.                             SetPort(whichWindow);
  357.                         end;
  358.  
  359.                 inDrag: 
  360.                     DragWindow(whichWindow, theEvent.where, DragLimits);
  361.  
  362.                 inGoAway: 
  363.                     if TrackGoAway(whichWindow, theEvent.where) then
  364.                         CloseAWindow(whichWindow);
  365.  
  366.                 inGrow: 
  367.                     begin (* Note: Add code to handle scroll bars here also!! *)
  368.                         sizeCode := GrowWindow(whichWindow, theEvent.where, SizeLimits);
  369.                         if (sizeCode <> 0) then
  370.                             SizeWindow(whichWindow, LoWord(sizeCode), HiWord(sizeCode), TRUE);
  371.                     end;
  372.  
  373.                 inZoomIn, inZoomOut: 
  374.                     begin
  375.                         ZoomWindow(whichWindow, location, FALSE);   (* We can zoom without coming to the front *)
  376.                 (* Add resizing code here too *)
  377.                     end;
  378.  
  379.                 inSysWindow: 
  380.                     SystemClick(theEvent, whichWindow);
  381.                 otherwise
  382.             end; (* case *)
  383.         end; (* DoMouseDown *)
  384.  
  385.  
  386.         procedure DoKeyDown (theEvent: EventRecord);
  387.             var
  388.                 ch: char;
  389.                 MenuCode: longint;
  390.  
  391.         begin
  392.             if BitAnd(theEvent.modifiers, cmdKey) <> 0 then
  393.                 begin
  394.                     ch := CHR(BitAnd(theEvent.message, charCodeMask));
  395.                     if FrontWindow <> nil then
  396.                         EnableItem(fileMenu, ifClose)
  397.                     else
  398.                         DisableItem(fileMenu, ifClose);
  399.                     MenuCode := MenuKey(ch);
  400.                     DoMenus(menuCode);
  401.                 end;
  402.         end; (* DoKeyDown *)
  403.  
  404.  
  405.     begin
  406.         repeat
  407.             if (system.HasWNE) then
  408.                 realEvent := WaitNextEvent(everyEvent, theEvent, 15, nil)   (* Give up as much time as possible *)
  409.             else
  410.                 begin
  411.                     SystemTask;
  412.                     realEvent := GetNextEvent(everyEvent, theEvent);
  413.                 end;
  414.  
  415.             UnloadSeg(@InitMyDialogs);
  416.             
  417.             if HandleDialogEvents(theEvent) then (* it's been taken care of *)
  418.             else if AboutEventProc(theEvent) then (* Otherwise, this isn't a dialog event, so see if it belongs to the About window *)
  419.             else                (* Otherwise, this event belongs to something other than the About window *)
  420.                 case theEvent.what of
  421.                     mouseDown: 
  422.                         DoMouseDown(theEvent);
  423.  
  424.                     keyDown: 
  425.                         DoKeyDown(theEvent);                        
  426.                     
  427.                     otherwise
  428.                 end; (* case *)
  429.         until Quit;
  430.     end; (* mainLoop *)
  431.  
  432.     procedure Shutdown;
  433.     begin
  434.         CloseMemoryDialog;
  435.     end; (* Shutdown *)
  436.  
  437. begin
  438.     Initialize;
  439.     OpenMemoryDialog;
  440.     MainLoop;
  441.     Shutdown;
  442. end.